package com.ruoyi.project.rate.controller;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ruoyi.common.utils.security.ShiroUtils;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.page.TableDataInfo;
import com.ruoyi.framework.web.service.DictService;
import com.ruoyi.project.rate.Constants;
import com.ruoyi.project.rate.KhRuleComparator;
import com.ruoyi.project.rate.Utils;
import com.ruoyi.project.rate.domain.Kh;
import com.ruoyi.project.rate.domain.KhRule;
import com.ruoyi.project.rate.domain.Rule;
import com.ruoyi.project.rate.service.KhRuleService;
import com.ruoyi.project.rate.service.KhService;
import com.ruoyi.project.rate.service.KhzDeptService;
import com.ruoyi.project.rate.service.RuleService;
import com.ruoyi.project.system.dept.domain.Dept;
import com.ruoyi.project.system.dept.service.IDeptService;
import com.ruoyi.project.system.dict.domain.DictData;
import com.ruoyi.project.system.user.domain.User;

@Controller
@RequestMapping("/rate/kh")
public class KhController extends BaseController {
	private static final BigDecimal ZERO = new BigDecimal("0");
	
	@Autowired
	private KhService khService;
	@Autowired
	private KhRuleService khRuleService;
	@Autowired
	private KhzDeptService khzDeptService;
	@Autowired
	private RuleService ruleService;
	@Autowired
	private IDeptService deptService;
	@Autowired
	private DictService dictService;

	@RequestMapping("/kh")
	public String kh(Kh kh, ModelMap mmap) {
		String pageFlag = kh.getPageFlag();
		String type = kh.getType();
		if (StringUtils.isBlank(pageFlag)) {
			throw new RuntimeException("请求参数错误, pageFlag is blank.");
		}
		if (StringUtils.isBlank(type)) {
			throw new RuntimeException("请求参数错误, type is blank.");
		}
		
		if (StringUtils.equalsAny(pageFlag,
				Constants.KH_STATUS_KHZ, Constants.KH_STATUS_FGLD, Constants.KH_STATUS_HZ)
				&& !StringUtils.equals(Constants.KH_TYPE_KHB_ZB, type)) {
			kh.setStatus(pageFlag);
		}
		
		kh.setMonthId(Utils.lastMonth());
		mmap.put("kh", kh);
		mmap.put("khzList", Utils.getKhzListByPageFlag(pageFlag));
		if (StringUtils.equals(Constants.KH_TYPE_KHB_ZB, type)) {
			mmap.put("khzList", dictService.getType(Constants.KHZ));
		}
		mmap.put("fgldList", Utils.fgldList());
		
		if (StringUtils.equals(Constants.KH_TYPE_KHB_ZB, type)) {
			mmap.put("deptList", Utils.level2DeptList());
		}

		return "rate/khList";
	}

	@PostMapping("/list")
	@ResponseBody
	public TableDataInfo list(Kh kh) {
		String pageFlag = kh.getPageFlag();
		if (StringUtils.isBlank(pageFlag)) {
			throw new RuntimeException("请求参数错误, pageFlag is blank.");
		}
		if (Constants.PAGE_FLAG_SUBMIT.equals(pageFlag)) {
			kh.setCreateDept(ShiroUtils.getSysDept());
		} else if (Constants.PAGE_FLAG_KHZ.equals(pageFlag)) {
			// 考核组审核时只能看到本组的单据
			List<DictData> khzList = this.khzDeptService.getKhzDictDataDept(ShiroUtils.getSysDept());
			for (DictData dd : khzList) {
				kh.getKhzList().add(dd.getDictValue());
			}
		} else if (Constants.PAGE_FLAG_FGLD.equals(pageFlag)) {
			// 监狱领导审核
			kh.setFgldChecker(ShiroUtils.getSysUser());
		}

		startPage();
		List<Kh> list = this.khService.findList(kh);

		return getDataTable(list);
	}

	@RequestMapping("/add")
	public String add(Kh kh, ModelMap mmap) {
		if (StringUtils.isBlank(kh.getType())) {
			throw new RuntimeException("type is blank.");
		}
		if (StringUtils.isBlank(kh.getKhz())) {
			throw new RuntimeException("请选择考核组.");
		}

		kh.setMonthId(Utils.lastMonth());
		kh.setCreateDept(ShiroUtils.getSysDept());
		kh.setPageFlag(Constants.PAGE_FLAG_ADD);
		
		// 校验是否存在考核组 针对考核办考核，则不校验
		List<DictData> khzList = Utils.getKhzListByPageFlag(kh.getPageFlag());
		if (StringUtils.equals(Constants.KH_TYPE_KHB_ZB, kh.getType())) {
			khzList = dictService.getType(Constants.KHZ);
		}
		if (khzList.size() == 0) {
			throw new RuntimeException("查询不到【" + kh.getCreateDept().getDeptName() + "】对应的考核组");
		}
		mmap.put("khzList", khzList);
		
		List<Dept> deptList;
		if (Constants.KH_TYPE_DU.equals(kh.getType())) {
			deptList = Utils.level2DeptList();
		} else if (Constants.KH_TYPE_KHB_ZB.equals(kh.getType())) {
			// 综合考核办公室主办考核，createDept需要设置为被考核部门
			if (kh.getDept() == null || kh.getDept().getDeptId() == null || kh.getDept().getDeptId().equals(0L)) {
				throw new RuntimeException("请选择被考核单位.");
			}
			Dept _d = this.deptService.selectDeptById(kh.getDept().getDeptId());
			if (_d == null) {
				throw new RuntimeException("被考核单位不存在，deptid=" + kh.getDept().getDeptId());
			}
			kh.setDept(_d);
			deptList = new ArrayList<>();
			deptList.add(kh.getDept());
		} else {
			deptList = new ArrayList<>();
			deptList.add(ShiroUtils.getSysDept());
			kh.setDept(ShiroUtils.getSysDept());
		}
		mmap.put("deptList", deptList);
		mmap.put("kh", kh);
		mmap.put("khRuleList", this.buildKhRuleListForEdit(kh, false));

		return "rate/khForm";
	}

	@RequestMapping("/edit")
	public String edit(Kh kh, ModelMap mmap) {
		Kh s = this.khService.get(kh);
		if (s == null) {
			throw new RuntimeException("找不到对应的数据！");
		}
		s.setPageFlag(kh.getPageFlag());
		s.setReserveStatus(kh.getReserveStatus());

		mmap.put("kh", s);
		mmap.put("khzList", Utils.getKhzListByPageFlag(s.getPageFlag()));
		
		List<Dept> deptList;
		if (Constants.KH_TYPE_DU.equals(s.getType())) {
			deptList = Utils.level2DeptList();
		} else {
			deptList = new ArrayList<>();
			deptList.add(s.getDept());
		}
		mmap.put("deptList", deptList);
		
		// 除了编辑，其他功能均不展示不扣分的内容
		if (StringUtils.equals(s.getPageFlag(), Constants.PAGE_FLAG_EDIT)) {
			mmap.put("khRuleList", this.buildKhRuleListForEdit(kh, false));
		} else {
			mmap.put("khRuleList", this.buildKhRuleListForEdit(kh, true));
		}
		
		// 审核时需要展示审核区域
		String showCheckResult = "0";
		if (StringUtils.equalsAny(s.getPageFlag(),
				Constants.PAGE_FLAG_KHZ,
				Constants.PAGE_FLAG_FGLD,
				Constants.PAGE_FLAG_HZ)) {
			showCheckResult = "1";
		}
		mmap.put("showCheckResult", showCheckResult);
		
		// 考核组审核时需要选择分管领导
		List<User> fgldList = new ArrayList<User>();
		if (StringUtils.equals(Constants.PAGE_FLAG_KHZ, s.getPageFlag())) {
			fgldList = Utils.fgldList();
		}
		mmap.put("fgldList", fgldList);

		return "rate/khForm";
	}

	@PostMapping("/save")
	@ResponseBody
	public AjaxResult save(Kh kh, @RequestParam Map<String, String> requestMap) {
		String pageFlag = kh.getPageFlag();
		String type = kh.getType();
		if (StringUtils.isBlank(type)) {
			throw new RuntimeException("type is blank.");
		}
		if (StringUtils.isBlank(kh.getKhz())) {
			throw new RuntimeException("khz is blank.");
		}
		if (StringUtils.isBlank(kh.getMonthId())) {
			throw new RuntimeException("month is blank.");
		}
		if (!StringUtils.equalsAny(pageFlag, "ADD", "EDIT")) {
			throw new RuntimeException("error pageFlag.");
		}
		
		if (kh.getDept() == null || kh.getDept().getDeptId() == null || kh.getDept().getDeptId() == 0L) {
			throw new RuntimeException("please select dept.");
		}
		
		// check duplicated
		Kh exist = new Kh();
		exist.setMonthId(kh.getMonthId());
		exist.setKhz(kh.getKhz());
		exist.setType(kh.getType());
		exist.setDept(kh.getDept());
		exist.setCreateDept(kh.getCreateDept());
		List<Kh> exists = this.khService.findList(exist);
		Dept _dept = this.deptService.selectDeptById(kh.getDept().getDeptId());
		if (StringUtils.equals("ADD", pageFlag)) {
			// new kh
			if (StringUtils.isNotBlank(kh.getId())) {
				throw new RuntimeException("request param error, id is not blank.");
			}
			if (exists.size() > 0) {
				throw new RuntimeException("当月已提交【" + _dept.getDeptName() + "】的数据，无需重复提交！");
			}
		} else if (StringUtils.equals("EDIT", pageFlag)) {
			Kh _c = this.khService.get(kh);
			if (_c == null) {
				throw new RuntimeException("get kh from db error！");
			}
			
			for (Kh e : exists) {
				if (!e.getId().equals(kh.getId())) {
					throw new RuntimeException("当月已提交【" + _dept.getDeptName() + "】的数据，无需重复提交！");
				}
			}
		}
		
		List<KhRule> khRuleList = this.buildKhRuleListByRequest(kh, requestMap);
		
		String status = Constants.KH_STATUS_DRAFT;
		// 管理员编辑时仍旧保留原有的状态
		if (StringUtils.equals("1", kh.getReserveStatus())) {
			Kh _c = this.khService.get(kh);
			String currentStatus = _c.getStatus();
			if (StringUtils.isNotBlank(currentStatus)) {
				status = currentStatus;
			}
		}
		kh.setStatus(status);
		
		this.khService.save(kh, khRuleList);

		return AjaxResult.success("保存成功！");
	}
	
	@RequestMapping("/submitToCheck")
	@ResponseBody
	public AjaxResult submitToCheck(Kh kh) {
		if (StringUtils.isBlank(kh.getId())) {
			throw new RuntimeException("请求参数id错误！");
		}

		kh = this.khService.get(kh);
		if (kh == null) {
			throw new RuntimeException("can not find kh！");
		}

		this.khService.submitToCheck(kh);

		return AjaxResult.success("提交审核成功！");
	}
	@PostMapping("/batchSubmitToCheck")
	@ResponseBody
	public AjaxResult batchSubmitToCheck(String ids, Kh kh) {
		if (StringUtils.isBlank(kh.getPageFlag())) {
			throw new RuntimeException("请求参数pageFlag为空！");
		}

		if (StringUtils.isBlank(ids)) {
			throw new RuntimeException("请求参数ids错误！");
		}
		
		int i = this.khService.batchSubmitToCheck(kh, ids);
		
		return AjaxResult.success("批量提交审核【" + i + "】条记录！");
	}

	@PostMapping("/submitCheck")
	@ResponseBody
	public AjaxResult submitCheck(Kh kh) {
		String pageFlag = kh.getPageFlag();
		if (StringUtils.isBlank(pageFlag)) {
			throw new RuntimeException("请求参数pageFlag为空！");
		}

		if (StringUtils.isBlank(kh.getId())) {
			throw new RuntimeException("请求参数id错误！");
		}
		
		this.khService.submitCheck(kh);

		return AjaxResult.success("审核成功！");
	}
	@PostMapping("/batchSubmitCheck")
	@ResponseBody
	public AjaxResult batchSubmitCheck(String ids, Kh kh) {
		if (StringUtils.isBlank(kh.getPageFlag())) {
			throw new RuntimeException("请求参数pageFlag为空！");
		}
		
		if (StringUtils.isBlank(kh.getCheckResult())) {
			throw new RuntimeException("请求参数checkResult为空！");
		}

		if (StringUtils.isBlank(ids)) {
			throw new RuntimeException("请求参数ids错误！");
		}
		
		if (Constants.PAGE_FLAG_KHZ.equals(kh.getPageFlag())) {
			if (kh.getFgldChecker() == null
					|| kh.getFgldChecker().getUserId() == null
					|| kh.getFgldChecker().getUserId() <= 0L) {
				throw new RuntimeException("请选择对应的分管领导！");
			}
		}
		
		int i = this.khService.batchSubmitCheck(kh, ids);
		
		return AjaxResult.success("批量审核成功【" + i + "】条记录！");
	}

	@RequestMapping("/cancelCheck")
	@ResponseBody
	public AjaxResult cancelCheck(Kh kh) {
		if (kh == null || StringUtils.isBlank(kh.getPageFlag())) {
			throw new RuntimeException("请求参数pageFlag为空！");
		}

		if (StringUtils.isBlank(kh.getId())) {
			throw new RuntimeException("请求参数id错误！");
		}
		
		this.khService.cancelCheck(kh);

		return AjaxResult.success("撤销审核成功！");
	}
    
    /**
     * 撤回报表
     * @param id
     * @param mmap
     * @return
     */
    @RequestMapping("/cancelSubmit")
    @ResponseBody
    public AjaxResult cancel(Kh kh) {
    	kh = this.khService.get(kh);
		if (kh == null) {
			throw new RuntimeException("找不到对应的数据！");
		}
		
		if (!Constants.KH_STATUS_KHZ.equals(kh.getStatus())) {
			throw new RuntimeException("当前申请状态不允许当前操作！");
		}
		
		this.khService.cancel(kh);
		
    	return AjaxResult.success("撤回成功！");
    }
    @PostMapping("/batchCancel")
	@ResponseBody
	public AjaxResult batchCancel(String ids, Kh kh) {
		if (StringUtils.isBlank(kh.getPageFlag())) {
			throw new RuntimeException("请求参数pageFlag为空！");
		}
		if (StringUtils.isBlank(ids)) {
			throw new RuntimeException("请求参数ids错误！");
		}
		int i = this.khService.batchCancel(kh, ids);
		
		return AjaxResult.success("批量撤回申请成功【" + i + "】条记录！");
	}
    
    /**
     * 考核办提交，直接通过
     * @param kh
     * @return
     */
    @RequestMapping("/khbSubmit")
	@ResponseBody
	public AjaxResult khbSubmit(Kh kh) {
		if (StringUtils.isBlank(kh.getId())) {
			throw new RuntimeException("请求参数khId错误！");
		}

		kh = this.khService.get(kh);
		if (kh == null) {
			throw new RuntimeException("can not find kh！");
		}
		
		kh.setStatus(Constants.KH_STATUS_APPROVED);
		this.khService.updateStatus(kh);

		return AjaxResult.success("提交成功！");
	}
    @RequestMapping("/cancelKhbSubmit")
	@ResponseBody
	public AjaxResult cancelKhbSubmit(Kh kh) {
		if (StringUtils.isBlank(kh.getId())) {
			throw new RuntimeException("请求参数khId错误！");
		}

		kh = this.khService.get(kh);
		if (kh == null) {
			throw new RuntimeException("can not find kh！");
		}
		
		kh.setStatus(Constants.KH_STATUS_DRAFT);
		this.khService.updateStatus(kh);

		return AjaxResult.success("撤回成功！");
	}
    
	
	@RequestMapping("/delete/{id}")
    @ResponseBody
    public AjaxResult delete(@PathVariable("id") String id) {
    	if (StringUtils.isBlank(id)) {
    		throw new RuntimeException("请求参数错误：【id=" + id + "】");
    	}
    	
    	Kh kh = this.khService.get(id);
		if (kh == null) {
			throw new RuntimeException("找不到对应的数据！");
		}
		
		this.khService.delete(kh);
		
    	return AjaxResult.success("删除成功！");
	}
	
	private List<KhRule> buildKhRuleListForEdit(Kh kh, boolean removeZero) {
		List<KhRule> khRuleList;
		if (StringUtils.isBlank(kh.getId())) {
			khRuleList = new ArrayList<>();
			
			Rule rule = new Rule();
			rule.setKhz(kh.getKhz());
			rule.setType(kh.getType());
			if (Constants.KH_TYPE_KHB_ZB.equals(kh.getType())) {
				// 针对考核组主办考核，需要根据被考核单位选择考核细则
				rule.setDept(kh.getDept());
				rule.setType(Constants.KH_TYPE_ZHU);
			} else {
				rule.setDept(kh.getCreateDept());
			}
			List<Rule> ruleList = this.ruleService.findList(rule);
			
			for (Rule r : ruleList) {
				KhRule khRule = new KhRule();
				khRule.setRuleId(r.getId());
				khRule.setKhz(r.getKhz());
				khRule.setType(r.getType());
				khRule.setLb(r.getLb());
				khRule.setDept(r.getDept());
//				if (khRule.getDept() == null || khRule.getDept().getDeptId() == 0) {
//					khRule.setDept(kh.getCreateDept());
//				}
				khRule.setXm(r.getXm());
				khRule.setXh(r.getXh());
				khRule.setFz(r.getFz());
				khRule.setNr(r.getNr());
				khRule.setFs(r.getFs());
				khRuleList.add(khRule);
			}
		} else {
			KhRule khRule = new KhRule();
			khRule.setKh(kh);
			khRuleList = this.khRuleService.findList(khRule);
		}
		
		if (removeZero) {
			BigDecimal zero = new BigDecimal("0");
			Iterator<KhRule> it = khRuleList.iterator();
			while (it.hasNext()) {
				KhRule k = it.next();
				if (k.getKf() == null || k.getKf().compareTo(zero) == 0) {
					it.remove();
				}
			}
		}
		
		Collections.sort(khRuleList, new KhRuleComparator());

		int i = 1;
		for (KhRule r : khRuleList) {
			r.setRelaId(i + "");
			i++;
		}

		return khRuleList;
	}
	
	private List<KhRule> buildKhRuleListByRequest(Kh kh, Map<String, String> requestMap) {
		List<KhRule> khRuleList = new ArrayList<>();
		Map<String,Dept> deptMap = Utils.mapDeptByDeptId();
		BigDecimal totalKf = new BigDecimal("0");
		
		for (Map.Entry<String, String> entry : requestMap.entrySet()) {
			String key = entry.getKey();
			if (key.startsWith("kh_rule_id_")) {
				String relaId = key.substring(key.lastIndexOf("_") + 1);

				KhRule khRule = new KhRule();
				khRule.setId(requestMap.get("kh_rule_id_" + relaId));
				
				if (Constants.PAGE_FLAG_ADD.equals(kh.getPageFlag())) {
					khRule.setRuleId(requestMap.get("kh_rule_ruleId_" + relaId));
					khRule.setKhz(requestMap.get("kh_rule_khz_" + relaId));
					khRule.setType(requestMap.get("kh_rule_type_" + relaId));
					khRule.setLb(requestMap.get("kh_rule_lb_" + relaId));
					khRule.setXm(requestMap.get("kh_rule_xm_" + relaId));
					khRule.setXh(requestMap.get("kh_rule_xh_" + relaId));
					khRule.setFz(requestMap.get("kh_rule_fz_" + relaId));
					khRule.setNr(requestMap.get("kh_rule_nr_" + relaId));
					khRule.setFs(requestMap.get("kh_rule_fs_" + relaId));
					
					String deptId = requestMap.get("kh_rule_deptId_" + relaId);
					Dept dept = deptMap.get(deptId);
					if (StringUtils.isNotBlank(deptId) && dept == null) {
						throw new RuntimeException("找不到部门：" + deptId);
					}
					khRule.setDept(dept);
				}
				
				String input = requestMap.get("kh_rule_kf_" + relaId);
				if (StringUtils.isNotBlank(input)) {
					// 不再校验正负值
					/**
					if (input.contains("-")) {
						throw new RuntimeException("扣分项请输入正数，" + input);
					}
					**/
					String fz = null;
					try {
						BigDecimal b = new BigDecimal(input);
						if (b.compareTo(ZERO) != 0) {
							khRule.setKf(b);
						}
						fz = b.toString();
					} catch (Exception e) {
						throw new RuntimeException("转换数字失败：" + input);
					}
					
					// 必须是0.5的倍数
					if (StringUtils.isNotBlank(fz)) {
						if (fz.contains(".")) {
							if (fz.endsWith(".5") || fz.endsWith(".50")
									|| fz.endsWith(".0") || fz.endsWith(".00")) {
								
							} else {
								throw new RuntimeException("分数最小单位为0.5【" + fz + "】");
							}
						}
					}
					
					totalKf = totalKf.add(khRule.getKf());
				}
				khRule.setRemark(requestMap.get("kh_rule_remark_" + relaId));
				khRule.setZrr(requestMap.get("kh_rule_zrr_" + relaId));
				
				khRuleList.add(khRule);
			}
		}
		
		kh.setKf(totalKf);
		return khRuleList;
	}
}